package co.yixiang.modules.system.service.impl;

import co.yixiang.modules.system.domain.Dept;
import co.yixiang.modules.system.domain.YxSales;
import co.yixiang.modules.system.domain.YxSalesManage;
import co.yixiang.modules.system.repository.YxSalesManageRepository;
import co.yixiang.modules.system.repository.YxSalesRepository;
import co.yixiang.modules.system.service.DeptService;
import co.yixiang.modules.system.service.YxSalesService;
import co.yixiang.modules.system.service.dto.*;
import co.yixiang.modules.system.service.mapper.YxSalesMapper;
import co.yixiang.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author frq
 * @date 2020-05-25
 */
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class YxSalesServiceImpl implements YxSalesService {

    @Autowired
    private YxSalesRepository salesRepository;
    @Autowired
    private YxSalesMapper salesMapper;

    private final PasswordEncoder passwordEncoder;

    @Autowired
    private DeptService deptService;

    @Autowired
    private YxSalesManageRepository salesManageRepository;

    public YxSalesServiceImpl(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public Map<String, Object> queryAll(YxSalesQueryCriteria criteria, Pageable pageable) {
        Page<YxSales> page = salesRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder), pageable);
        List<YxSalesDTO> list = new ArrayList<>();
        if (!page.getContent().isEmpty()) {
            for (YxSales sales : page.getContent()) {
                YxSalesDTO dto = salesMapper.toDto(sales);
                if (dto.getDeptId() != null) {
                    DeptDTO dept = deptService.findById(Long.parseLong(dto.getDeptId()));
                    dto.setDeptName(dept.getName());
                }
                List<Integer> listManage = salesManageRepository.findByManageUid(dto.getUid());
                if (!listManage.isEmpty()) {
                    Integer[] uids = new Integer[listManage.size()];
                    for (int i = 0; listManage.size() > i; i++) {
                        uids[i] = listManage.get(i);
                    }
                    dto.setUids(uids);
                }
                list.add(dto);
            }
        }
        Map<String, Object> map = new LinkedHashMap<>(2);
        map.put("content", list);
        map.put("totalElements", page.getTotalElements());
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void create(YxSalesDTO resources) {
        YxSales yxSales = salesMapper.toEntity(resources);
        yxSales.setAddTime(new Date());
        yxSales.setPwdPlaintext(resources.getPassword());
        yxSales.setPassword(passwordEncoder.encode(resources.getPassword()));
        yxSales.setLastTime(new Date());
        salesRepository.save(yxSales);
        if (resources.getSalesId() != null) {
            Iterator<Long> it = resources.getSalesId().iterator();
            while (it.hasNext()) {
                Integer salesId = it.next().intValue();
                YxSalesManage salesManage = new YxSalesManage();
                salesManage.setUid(salesId);
                salesManage.setManageUid(yxSales.getUid());
                salesManage.setAddTime(new Date());
                salesManageRepository.save(salesManage);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(YxSalesDTO resources) {
        YxSales yxSales = salesRepository.findById(resources.getUid()).orElseGet(YxSales::new);
        ValidationUtil.isNull(yxSales.getUid(), "YxSales", "id", resources.getUid());
        YxSales sales = salesMapper.toEntity(resources);
        yxSales.copy(sales);
        salesRepository.save(yxSales);
        //选择主管时，删除原有业务员
        salesManageRepository.deleteManageUid(sales.getUid());
        if (resources.getSalesId() != null) {
            Iterator<Long> it = resources.getSalesId().iterator();
            while (it.hasNext()) {
                Integer salesId = it.next().intValue();
                YxSalesManage salesManage = new YxSalesManage();
                salesManage.setUid(salesId);
                salesManage.setManageUid(yxSales.getUid());
                salesManage.setAddTime(new Date());
                salesManageRepository.save(salesManage);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(Integer[] ids) {
        for (Integer id : ids) {
            salesRepository.deleteById(id);
            salesManageRepository.deleteManageId(id);
        }
    }

    /**
     * 通过部门ID查询业务员
     *
     * @param deptId
     * @return
     */
    @Override
    public List<YxSales> findDetpListUser(String deptId) {
        YxSales yxSales = new YxSales();
        yxSales.setStatus(true);
        yxSales.setDeptId(deptId);
        yxSales.setGroupId(1);
        Example<YxSales> example = Example.of(yxSales);
        List<YxSales> list = salesRepository.findAll(example);
        return list;
    }

    /**
     * 通过账户查询业务员
     *
     * @param userName
     * @return
     */
    @Override
    public YxSales findUserNameUser(String userName) {
        YxSales yxSales = new YxSales();
        yxSales.setStatus(true);
        yxSales.setUsername(userName);
        Example<YxSales> example = Example.of(yxSales);
        Optional<YxSales> optional = salesRepository.findOne(example);
        if (optional.isPresent()) {
            return optional.get();
        } else {
            return null;
        }
    }

    /**
     * 不分页查询全部数据
     *
     * @param criteria
     * @return
     */
    @Override
    public List<YxSalesDTO> queryAll(YxSalesQueryCriteria criteria) {
        List<YxSales> users = salesRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root, criteria, criteriaBuilder));
        return salesMapper.toDto(users);
    }

    /**
     * 导出数据
     *
     * @param queryAll 待导出的数据
     * @param response /
     * @throws IOException /
     */
    @Override
    public void download(List<YxSalesDTO> queryAll, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (YxSalesDTO yxSalesDTO : queryAll) {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("用户名", yxSalesDTO.getRealName());
            map.put("手机号", yxSalesDTO.getPhone());
            if (1==yxSalesDTO.getGroupId()) {
                map.put("级别", "普通业务员");
            } else if (2==yxSalesDTO.getGroupId()) {
                map.put("级别", "主管");
            } else if (3==yxSalesDTO.getGroupId()) {
                map.put("级别", "集团员工");
            } else if (4==yxSalesDTO.getGroupId()) {
                map.put("级别", "总监");
            }else{
                map.put("级别", "总监");
            }
            map.put("账号", yxSalesDTO.getUsername());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}